import abc

#声明一个抽象类并且指定当前类的元类
class Human(metaclass=abc.ABCMeta):

    #定义一个抽象类的方法
    @abc.abstractmethod
    def smoking(self):
        pass

    @abc.abstractmethod
    def drink(self):
        pass

    @abc.abstractmethod
    def play(self):
        pass


    def sleep(self):
        print("Sleeping...")

class Teacher(Human):
    def smoking(self):
        print("teacher like smoking")
    def drink(self):
        print("teacher drink wine")

    def play(self):
        print("teacher play games with student")

class Student(Human):
    def smoking(self):
        print("student don't allow to smoke")
    def drink(self):
        print("student drink water")

    def play(self):
        print("student have no time to play")

t = Teacher()
s = Student()
t.play()
s.play()




class A():
    pass

def say(self):
    print("saying...")

A.say = say #其实就是把函数名当变量使用了，从而实现将方法绑定在类A上
a = A()
a.say()

from types import MethodType
class B():
    pass

def play(self):
    print("Playing...")

b = B()
# b.play = play  #直接将方法绑定在实例上是不行的，会报错
b.play = MethodType(play, B)
b.play()

# 利用Type造一个类
def eat(self):
    print("eating...")

def sleep(self):
    print("sleeping")

C = type("Animal", (object,), {"class_eat": eat, "class_sleep":sleep})
c = C()
c.class_eat()
c.class_sleep()

#MetaClass
class MyMetaClass(type):
    def __new__(cls, name, bases, attrs):
        attrs['id'] = '00000'
        attrs['name'] = "zhangsan"
        return type.__new__(cls, name, bases, attrs)

class MyClass(object,metaclass=MyMetaClass):
    pass

m = MyClass()
print(m.id)
print(m.name)